// Simple Bison's grammar having code, printf("OK!\n"); precisely, that will never get executed because of being placed after the YYERROR macro.
// When the manual says YYERROR is to be used in actions, it's meant strictly, in the sense that everywhere that's not strictly the body of a Bison's action remains excluded, for instance a function called therein from.
%{
#include <stdio.h>
int yylex();
void yyerror(char const *s);
void dummy();
void destroy_environment();
%}

%%
/* A question on YYRECOVERING()'s usefullness:
 1. Since error detection and At error raising (with YYERROR) rule's actions stop executing.
 2. Outside a rule's action YYRECOVERING() seems not be allowed
 3. Rule's action execution resumes but right after parser is recovered from error
 So while error is being in effect actions are not. Unlike the function yylex(), for example, that can be called in either normal or error state, actions will mostly executed in normal mode.
 So YYRECOVERING()'s purpose is to determine if an error recovery is ongoing, and it turns out in the places where execution can reach it errors cannot. Except the trivial usage being done at following (so trivial that YYRECOVERING() could be easily replaced by a user-managed flag): What am I missing?
 */
S: T {printf("S:T   YYRECOVERING(): %d\n",YYRECOVERING()); destroy_environment();}
 | error {  char c[2]; printf("End error?"); scanf("%s", c); if(c[0]=='y')yyerrok; printf("S:error   YYRECOVERING(): %d\n",YYRECOVERING()); if(YYRECOVERING())destroy_environment();}
;
T: {printf("preparing environment...\n"); dummy();  char c[2]; printf("Raise error?"); scanf("%s", c); if(c[0]=='y')YYERROR; printf("OK!\n");}
%%
int yylex() {
  return 0;
}

void yyerror(char const *s) {
fprintf(stderr, "%s\n", s);
}

int main() {
yyparse();
return 0;
}

void dummy() {
// YYERROR not allowed but in a rule's action.
printf("dummy\n");
}

void destroy_environment() {
// YYRECOVERING not allowed but in a rule's action
	printf("destroying environment\n");

}